<!DOCTYPE html>



  


<html class="theme-next pisces use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
















  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />







<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="Hexo, NexT" />










<meta name="description" content="@Author:songxiankun2008@126.com  1.分布式面临问题 CAP/BASE理论 zookeeper能做什么 ACID 事务 单机数据库的 一致性 跨库事务 分布式事务 尽量避免 CAP理论： Consistency（一致性） 一致性（C）：在分布式系统中的所有数据备份，在同一时刻是否同样的值。（等同于所有节点访问同一份最新的数据副本）   Availability（可">
<meta property="og:type" content="article">
<meta property="og:title" content="zookeeper">
<meta property="og:url" content="http://smallkk.gitee.io/2018/03/11/zookeeper/index.html">
<meta property="og:site_name" content="Hi , 小坤坤">
<meta property="og:description" content="@Author:songxiankun2008@126.com  1.分布式面临问题 CAP/BASE理论 zookeeper能做什么 ACID 事务 单机数据库的 一致性 跨库事务 分布式事务 尽量避免 CAP理论： Consistency（一致性） 一致性（C）：在分布式系统中的所有数据备份，在同一时刻是否同样的值。（等同于所有节点访问同一份最新的数据副本）   Availability（可">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="e:/YoudaoNote/pic/zookeeper/1.jpg">
<meta property="og:image" content="e:/YoudaoNote/pic/zookeeper/2.jpg">
<meta property="og:image" content="e:/YoudaoNote/pic/zookeeper/3.jpg">
<meta property="og:image" content="e:/YoudaoNote/pic/zookeeper/4.jpg">
<meta property="og:image" content="e:/YoudaoNote/pic/zookeeper/5.jpg">
<meta property="og:image" content="e:/YoudaoNote/pic/zookeeper/6.jpg">
<meta property="og:image" content="e:/YoudaoNote/pic/zookeeper/7.jpg">
<meta property="og:image" content="e:/YoudaoNote/pic/zookeeper/8.jpg">
<meta property="og:image" content="e:/YoudaoNote/pic/zookeeper/9.jpg">
<meta property="og:image" content="e:/YoudaoNote/pic/zookeeper/10.jpg">
<meta property="og:image" content="e:/YoudaoNote/pic/zookeeper/11.jpg">
<meta property="og:updated_time" content="2018-04-30T19:07:40.862Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="zookeeper">
<meta name="twitter:description" content="@Author:songxiankun2008@126.com  1.分布式面临问题 CAP/BASE理论 zookeeper能做什么 ACID 事务 单机数据库的 一致性 跨库事务 分布式事务 尽量避免 CAP理论： Consistency（一致性） 一致性（C）：在分布式系统中的所有数据备份，在同一时刻是否同样的值。（等同于所有节点访问同一份最新的数据副本）   Availability（可">
<meta name="twitter:image" content="e:/YoudaoNote/pic/zookeeper/1.jpg">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Pisces',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://smallkk.gitee.io/2018/03/11/zookeeper/"/>





  <title>zookeeper | Hi , 小坤坤</title>
  








</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">Hi , 小坤坤</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle"></p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://smallkk.gitee.io/2018/03/11/zookeeper/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="S-Name Small·kk">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avatar.gif">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Hi , 小坤坤">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">zookeeper</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-03-11T09:30:52+08:00">
                2018-03-11
              </time>
            

            

            
          </span>

          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <blockquote>
<p>@Author:<a href="mailto:songxiankun2008@126.com" target="_blank" rel="noopener">songxiankun2008@126.com</a></p>
</blockquote>
<h5 id="1-分布式面临问题-CAP-BASE理论-zookeeper能做什么"><a href="#1-分布式面临问题-CAP-BASE理论-zookeeper能做什么" class="headerlink" title="1.分布式面临问题 CAP/BASE理论 zookeeper能做什么"></a>1.分布式面临问题 CAP/BASE理论 zookeeper能做什么</h5><hr>
<p>ACID 事务 单机数据库的 一致性</p>
<p>跨库事务 分布式事务 尽量避免</p>
<h6 id="CAP理论："><a href="#CAP理论：" class="headerlink" title="CAP理论："></a>CAP理论：</h6><ul>
<li>Consistency（一致性）<ul>
<li>一致性（C）：在分布式系统中的所有数据备份，在同一时刻是否同样的值。（等同于所有节点访问同一份最新的数据副本）</li>
</ul>
</li>
<li>Availability（可用性）<ul>
<li>可用性（A）：在集群中一部分节点故障后，集群整体是否还能响应客户端的读写请求。（对数据更新具备高可用性）</li>
</ul>
</li>
<li><p>Partition tolerance（分区容错性）</p>
<ul>
<li>分区容忍性（P）：以实际效果而言，分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性，就意味着发生了分区的情况，必须就当前操作在C和A之间做出选择。</li>
</ul>
</li>
<li><p>[x] 最多只能取其中两个  最多只能满足其中两个 不可能满足三个;如果是强一致性,就要牺牲可分片</p>
</li>
</ul>
<h6 id="BASE理论："><a href="#BASE理论：" class="headerlink" title="BASE理论："></a>BASE理论：</h6><p>==BASE==是指基本可用（Basically Available）、软状态（ Soft State）、最终一致性（ Eventual Consistency）。</p>
<ul>
<li><p>基本可用（Basically Available）</p>
<ul>
<li>基本可用是指分布式系统在出现故障的时候，允许损失部分可用性，即保证核心可用。</li>
<li>电商大促时，为了应对访问量激增，部分用户可能会被引导到降级页面，服务层也可能只提供降级服务。这就是损失部分可用性的体现。</li>
</ul>
</li>
<li><p>软状态（ Soft State）</p>
<ul>
<li>软状态是指允许系统存在中间状态，而该中间状态不会影响系统整体可用性。分布式存储中一般一份数据至少会有三个副本，允许不同节点间副本同步的延时就是软状态的体现。mysql replication的异步复制也是一种体现。</li>
</ul>
</li>
<li><p>最终一致性（ Eventual Consistency）</p>
<ul>
<li>最终一致性是指系统中的所有数据副本经过一定时间后，最终能够达到一致的状态。弱一致性和强一致性相反，最终一致性是弱一致性的一种特殊情况。</li>
</ul>
</li>
<li><p>弱状态</p>
<ul>
<li>(相当于是数据库的主从复制,这个时候主从节点的数据是不一致的所以称为弱状态,虽然最终结果数据会一致) </li>
</ul>
</li>
<li>最终一致性(表示数据暂时不一致,但是数据最终会一致的) <ul>
<li>最终一致性是弱一致性的一个特例，系统会保证在一定时间内，能够达到一个数据一致的状态。这里之所以将最终一致性单独提出来，是因为它是弱一致性中非常推崇的一种一致性模型，也是业界在大型分布式系统的数据一致性上比较推崇的模型   </li>
</ul>
</li>
<li>强一致性<ul>
<li>这种一致性级别是最符合用户直觉的，它要求系统写入什么，读出来的也会是什么，用户体验好，但实现起来往往对系统的性能影响大 </li>
</ul>
</li>
<li>弱一致性<ul>
<li>这种一致性级别约束了系统在写入成功后，不承诺立即可以读到写入的值，也不久承诺多久之后数据能够达到一致，但会尽可能地保证到某个时间级别（比如秒级别）后，数据能够达到一致状态</li>
</ul>
</li>
</ul>
<h6 id="ACID和BASE的区别与联系"><a href="#ACID和BASE的区别与联系" class="headerlink" title="ACID和BASE的区别与联系"></a>ACID和BASE的区别与联系</h6><ul>
<li>ACID是传统数据库常用的设计理念，追求强一致性模型。BASE支持的是大型分布式系统，提出通过牺牲强一致性获得高可用性。</li>
<li>ACID和BASE代表了两种截然相反的设计哲学，在分布式系统设计的场景中，系统组件对一致性要求是不同的，因此ACID和BASE又会结合使用。</li>
</ul>
<h6 id="zookeeper功能"><a href="#zookeeper功能" class="headerlink" title="zookeeper功能:"></a>zookeeper功能:</h6><ul>
<li>dubbo 服务治理框架 核心zk</li>
<li>发布订阅：redis mq zookeeper </li>
<li>负载均衡: ngix apache-http</li>
<li>命名服务：</li>
<li>分布式协调通知：</li>
<li>集群管理：</li>
<li>==Master选举==：</li>
<li>分布式锁: redis </li>
<li>分布式队列</li>
</ul>
<h6 id="分布式系统八大谬论"><a href="#分布式系统八大谬论" class="headerlink" title="分布式系统八大谬论:"></a>分布式系统八大谬论:</h6><ul>
<li>网络相当可靠</li>
<li>延迟为零</li>
<li>传输带宽是无限的</li>
<li>网络相当安全</li>
<li>拓扑结构不会改变</li>
<li>必须要有一名管理员</li>
<li>传输成本为零</li>
<li>网络同质化<h5 id="2-各种一致性协议解释"><a href="#2-各种一致性协议解释" class="headerlink" title="2.各种一致性协议解释"></a>2.各种一致性协议解释</h5></li>
</ul>
<hr>
<h6 id="高可用-一致性-取舍"><a href="#高可用-一致性-取舍" class="headerlink" title="高可用 一致性 取舍"></a>高可用 一致性 取舍</h6><p>一致性： 分布式事务 强一致性 2PC(2阶段提交) 3PC(3阶段提交)</p>
<p>高可用性 集群 服务拆分 ： 主从结构 Master选举<br>每个从节点保存的数据 不一致</p>
<p>Paxos算法:一致性协议</p>
<p>zookeeper的核心是一个选举算法(Paxos算法)，将各方面达成一致，几阶段提交那个的都不是重点</p>
<p><img src="E:/YoudaoNote/pic/zookeeper/1.jpg" alt="image"></p>
<ul>
<li>上图是 2阶段提交的模型;下图是出现“事务中断”的时候全部回滚的模型(==*引入协调者进行凉着或者多个参与者进行协调==)<ul>
<li>缺点：单点故障(协调者只有一个,如果协调者挂掉)</li>
</ul>
</li>
</ul>
<p><img src="E:/YoudaoNote/pic/zookeeper/2.jpg" alt="image"></p>
<ul>
<li>下图是 3阶段提交的模型(每次都要询问是否准备好要开始提交)</li>
</ul>
<p><img src="E:/YoudaoNote/pic/zookeeper/3.jpg" alt="image"></p>
<p>在Java中的容器支持：</p>
<ul>
<li>JTA(java Transtion..)  </li>
<li><p>JBose(类似于Tomcat的一种容器)天生不支持JTA，但是引入一个包(JOTM 一个开源JTA实现)就可以</p>
</li>
<li><p>NWR(协议)： </p>
<ul>
<li>N（数据分片 节点） (下图有3个节点)</li>
<li>W 每次写入 写入多少阶段算成功  (根据下图,每次至少写入两个算成功)</li>
<li>R 每次读取 读取多少阶段算成功(根据下图,每次至少读取两个算成功)</li>
<li>在三个节点中,写两次读两次总会有一条数据是强一致性即总会读到正确的数据</li>
</ul>
</li>
</ul>
<p><img src="E:/YoudaoNote/pic/zookeeper/4.jpg" alt="image"></p>
<p>NWR值的不同组合会产生不同的一致性效果,当W+R&gt;N的时候,整个系统对于客户端来讲能保证强一致性;</p>
<p>兰伯特 推出Paxos 90年发表出来但是不想解释 2001年才勉强解释这个算法： Paxos made simple </p>
<p>在paxos算法中，分为4种角色：<br>  Proposer ：提议者<br>  Acceptor：决策者<br>  Client：产生议题者<br>  Learner：最终决策学习者</p>
<p><img src="E:/YoudaoNote/pic/zookeeper/5.jpg" alt="image"></p>
<p><strong>提案</strong>： 【编号 ， 值】 [K,V]</p>
<p>==规则==：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Acceptor：决策者 必须接受第一提案；</span><br><span class="line">    Acceptor：决策者 不能接受比K值小的提案</span><br><span class="line">    Proposer：提议者 必须获得多数节点的支持 否则就得继续提案直到获得多数支持</span><br><span class="line">  决议阶段： 如果有比k大的k+1值，那么就只能接受k+1的值，不能接受比(k+1)的值</span><br></pre></td></tr></table></figure>
<h6 id="Paxos协议分为两个阶段："><a href="#Paxos协议分为两个阶段：" class="headerlink" title="Paxos协议分为两个阶段："></a>Paxos协议分为两个阶段：</h6><p><em>此处有4个步骤…</em></p>
<ul>
<li>准备阶段</li>
<li>决议阶段</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">step1：，设置时钟：proposer令localClock=globalClock.incrementAndGet()。(全局时钟设置,这个是按时间顺序的,编号越后来的值越大)</span><br><span class="line"></span><br><span class="line">step2：prepare:proposer向所有Acceptor发送一个prepare消息。</span><br><span class="line">       接收方应返回它最近一次accept的value，以及 accept的时间，若在它还没有accept过value，那么就返回空。</span><br><span class="line">       proposer只有在收到过半数的response之后，才可进入下一个阶段。一旦收到reject消息，那么就重头来。</span><br><span class="line">       (超过半数即：如果有5个节点,要3个通过才算通过;如果有3个节点,2个通过算通过)</span><br><span class="line"></span><br><span class="line">step3：构造Proposal:proposer从prepare阶段收到的所有values中选取时间戳最新的一个。如果没有，那么它自己提议一个value。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">step4：发送Proposal:proposer把value发送给其它所有机器，消息的时间戳取自localClock。</span><br><span class="line">       接收方只要检查消息时间戳合法，那么就接受此value，把这个value和时间戳写入到硬盘上，然后答复OK，否则拒绝接受。</span><br><span class="line">       proposer若收到任何的reject答复，则回到 step1。否则，在收到过半数的OK后，此Proposal被通过</span><br></pre></td></tr></table></figure>
<p><strong>Phase1（准备阶段）</strong></p>
<ul>
<li style="list-style: none"><input type="checkbox" checked> 1. 每个Server都向Proposer发消息称自己要成为leader，Server1往Proposer1发、Server2往Proposer2发、Server3往Proposer3发；</li>
<li style="list-style: none"><input type="checkbox" checked> 2. 现在每个Proposer都接收到了Server1发来的消息但时间不一样，Proposer2先接收到了，然后是Proposer1，接着才是Proposer3；</li>
<li><p>[x] 3. Proposer2首先接收到消息所以他从系统中取得一个编号1，Proposer2向Acceptor2和Acceptor3发送一条，编号为1的消息；接着Proposer1也接收到了Server1发来的消息，取得一个编号2，Proposer1向Acceptor1和Acceptor2发送一条，编号为2的消息； 最后Proposer3也接收到了Server3发来的消息，取得一个编号3，Proposer3向Acceptor2和Acceptor3发送一条，编号为3的消息；</p>
</li>
<li><p>[x] 1. 这时Proposer1发送的消息先到达Acceptor1和Acceptor2，这两个都没有接收过请求所以接受了请求返回[2,null]给Proposer1，并承诺不接受编号小于2的请求；</p>
</li>
<li style="list-style: none"><input type="checkbox" checked> 2. 此时Proposer2发送的消息到达Acceptor2和Acceptor3，Acceprot3没有接收过请求返回[1,null]给Proposer2，并承诺不接受编号小于1的请求，但这时Acceptor2已经接受过Proposer1的请求并承诺不接受编号小于的2的请求了，所以Acceptor2拒绝Proposer2的请求；</li>
<li style="list-style: none"><input type="checkbox" checked> 3. 最后Proposer3发送的消息到达Acceptor2和Acceptor3，Acceptor2接受过提议，但此时编号为3大于Acceptor2的承诺2与Accetpor3的承诺1，所以接受提议返回[3,null];</li>
<li style="list-style: none"><input type="checkbox" checked> 4. Proposer2没收到过半的回复所以重新取得编号4，并发送给Acceptor2和Acceptor3，然后Acceptor2和Acceptor3通过<br><strong>Phase2（决议阶段）</strong></li>
<li style="list-style: none"><input type="checkbox" checked> 1. Proposer3收到过半（三个Server中两个）的返回，并且返回的Value为null，所以Proposer3提交了[3,server3]的议案；</li>
<li style="list-style: none"><input type="checkbox" checked> 2. Proposer1收到过半返回，返回的Value为null，所以Proposer1提交了[2,server1]的议案；</li>
<li style="list-style: none"><input type="checkbox" checked> 3. Proposer2收到过半返回，返回的Value为null，所以Proposer2提交了[4,server2]的议案；</li>
<li style="list-style: none"><input type="checkbox" checked> 4. Acceptor1、Acceptor2接收到Proposer1的提案[2,server1]请求，Acceptor2承诺编号大于4所以拒绝了通过，Acceptor1通过了请求；</li>
<li style="list-style: none"><input type="checkbox" checked> 5. Proposer2的提案[4,server2]发送到了Acceptor2、Acceptor3，提案编号为4所以Acceptor2、Acceptor3都通过了提案请求；</li>
<li style="list-style: none"><input type="checkbox" checked> 6. Acceptor2、Acceptor3接收到Proposer3的提案[3,server3]请求，Acceptor2、Acceptor3承诺编号大于4所以拒绝了提案；</li>
<li style="list-style: none"><input type="checkbox" checked> 7. 此时过半的Acceptor都接受了Proposer2的提案[4,server2],Larner感知到了提案的通过，Larner学习提案，server2成为Leader；</li>
</ul>
<p><img src="E:/YoudaoNote/pic/zookeeper/6.jpg" alt="image"></p>
<p>参考博客：</p>
<p><a href="http://linbingdong.com/2017/04/17/%E5%88%86%E5%B8%83%E5%BC%8F%E7%B3%BB%E5%88%97%E6%96%87%E7%AB%A0%E2%80%94%E2%80%94Paxos%E7%AE%97%E6%B3%95%E5%8E%9F%E7%90%86%E4%B8%8E%E6%8E%A8%E5%AF%BC/" target="_blank" rel="noopener">http://linbingdong.com/2017/04/17/%E5%88%86%E5%B8%83%E5%BC%8F%E7%B3%BB%E5%88%97%E6%96%87%E7%AB%A0%E2%80%94%E2%80%94Paxos%E7%AE%97%E6%B3%95%E5%8E%9F%E7%90%86%E4%B8%8E%E6%8E%A8%E5%AF%BC/</a></p>
<p><a href="https://segmentfault.com/a/1190000005717258" target="_blank" rel="noopener">https://segmentfault.com/a/1190000005717258</a></p>
<p><img src="E:/YoudaoNote/pic/zookeeper/7.jpg" alt="image"></p>
<h5 id="3-zookeeper原理-安装使用"><a href="#3-zookeeper原理-安装使用" class="headerlink" title="3. zookeeper原理 安装使用"></a>3. zookeeper原理 安装使用</h5><hr>
<ul>
<li><p>1.顺序一致性(不管有多少个分布式单位请求这个zookeeper，zookeeper处理他们的顺序一定是按照他们请求的顺序来的不会乱序；在真正分布式环境下达到顺序是很难保证的)</p>
</li>
<li><p>2.原子性(要么都把数据插入成功，要么都失败，不会有脏数据产生)</p>
</li>
<li><p>3.单一视图(无论有多少个客户连接了这个东西，那么所有的用户看到的这个界面都是一样的)</p>
</li>
<li><p>4.可靠性(相当于是ACID里面的持久性)</p>
</li>
<li><p>5.实时性(一个数据操作成功，用户就能立即刷新到数据，但是zookeeper保证的是在一定时间之内，是最终强一致性(最终强一致性的代价是效率的牺牲)</p>
</li>
<li><p>[x] zookeeper自身的安全性保障：==zookeeper本身就是一个分布式系统==(zookeeper自身就是一个单点故障问题) 一般部署奇数个zk服务器(奇数个是因为，少数服从多数，比如出现2:2的情况就只能无限循环下去，一般都是部署3,5台(为了高可用 可能会部署多台机器，就很难保证顺序一致性))</p>
</li>
</ul>
<ul>
<li style="list-style: none"><input type="checkbox" checked> paxos核心精髓 ，但是zk并没有直接采用paxos ，而是用了一种其他的算法,一套Zab算法,人们认为这种算法是基于paxos再改造的算法</li>
</ul>
<p>zab:  </p>
<ul>
<li><ol>
<li>第一：①原子广播((一直都只有一个Master,其他全部为slave))  ②数据同步(有了主从结构就会有这个数据同步) ③全局事务ID(根据这个ID来进行数据同步) </li>
</ol>
</li>
<li><ol start="2">
<li>第二： <strong>Master选举</strong><ul>
<li><ol>
<li>basic-paxos算法(模仿paxos算法)</li>
</ol>
</li>
<li><ol start="2">
<li>fast-paxos改进了basic-paxos算法</li>
</ol>
</li>
<li><ol start="3">
<li>zookeeper现在默认的是fast-paxos算法，当然可以把zk的算法改成basic-paxos算法<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">上面两个重点：</span><br><span class="line">1是Master选举,自身就是一个分布式集群;</span><br><span class="line">2是原子广播:要让所有地方的数据保持一致;跟“数据同步”“全局事务ID息息相关”</span><br></pre></td></tr></table></figure>
</li>
</ol>
</li>
</ul>
</li>
</ol>
</li>
</ul>
<h6 id="zookeeper如果是安装单机状态-就很容易保证上面的那5个特性-但是为了高可用就要用zookeeper来搭集群"><a href="#zookeeper如果是安装单机状态-就很容易保证上面的那5个特性-但是为了高可用就要用zookeeper来搭集群" class="headerlink" title="zookeeper如果是安装单机状态,就很容易保证上面的那5个特性;但是为了高可用就要用zookeeper来搭集群"></a>zookeeper如果是安装单机状态,就很容易保证上面的那5个特性;但是为了高可用就要用zookeeper来搭集群</h6><ol>
<li>复制三份zookeeper,并将各个conf里面的zoo_sample.cfg重命名为zoo.cfg表示配置启用</li>
<li>在第一个根目录下新建data文件夹用来存放数据,配置在下面的代码</li>
<li>修改第一个文件夹里面的zoo.cfg</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"># The number of milliseconds of each tick</span><br><span class="line">#心跳检测 2000ms</span><br><span class="line">tickTime=2000</span><br><span class="line"># The number of ticks that the initial </span><br><span class="line"># synchronization phase can take</span><br><span class="line">#初始化：这儿的10*2000得到的时间还是没有连接上的话就默认断开或者连接失败</span><br><span class="line">initLimit=10</span><br><span class="line"># The number of ticks that can pass between </span><br><span class="line"># sending a request and getting an acknowledgement</span><br><span class="line">#与Master跟slave之间或者slave与slave之间进行数据同步的时候5*2000</span><br><span class="line">#得到的时间内如果对方没有回应,或(ACK:acknowledgement)机制反馈的话就表明挂掉了</span><br><span class="line">#此时就可能需要新的投票什么的</span><br><span class="line">syncLimit=5</span><br><span class="line"># the directory where the snapshot is stored.</span><br><span class="line"># do not use /tmp for storage, /tmp here is just </span><br><span class="line"># example sakes.</span><br><span class="line">dataDir=G:/Plugins/zookeeper-Group/zookeeper-3.4.10-1/data</span><br><span class="line"># the port at which the clients will connect</span><br><span class="line">#后面的集群端口号要不一致</span><br><span class="line">clientPort=2181</span><br><span class="line"># the maximum number of client connections.</span><br><span class="line"># increase this if you need to handle more clients</span><br><span class="line">#maxClientCnxns=60</span><br><span class="line">#</span><br><span class="line"># Be sure to read the maintenance section of the </span><br><span class="line"># administrator guide before turning on autopurge.</span><br><span class="line">#</span><br><span class="line"># http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance</span><br><span class="line">#</span><br><span class="line"># The number of snapshots to retain in dataDir</span><br><span class="line">#autopurge.snapRetainCount=3</span><br><span class="line"># Purge task interval in hours</span><br><span class="line"># Set to &quot;0&quot; to disable auto purge feature</span><br><span class="line">#autopurge.purgeInterval=1</span><br><span class="line">#此处是新增的</span><br><span class="line">server.1=localhost:2887:3887</span><br><span class="line">server.2=localhost:2888:3888</span><br><span class="line">server.3=localhost:2889:3889</span><br><span class="line">#此处是在本机搭建了3台集群,</span><br><span class="line">#localhost表示这个节点的ip,</span><br><span class="line">#第一个端口表明数据同步的时候的ip,</span><br><span class="line">#第二个ip表示如果服务器挂掉后进行Master选举的时候要用的端口</span><br></pre></td></tr></table></figure>
<ol start="4">
<li>将第二个第三个文件夹也类似修改配置,只是客户端的端口号不一致,存放数据data的文件夹的路径不一致;其他一致</li>
<li>分别在第一个第二个第三个文件夹的data文件夹中新建文件“myid(无后缀)”,在里面写上这是第几个节点,即里面的内容分别为1、 2、 3</li>
<li>启动：顺次进入第一二三的bin文件夹里面启zkServer.cmd(共启动三个zkServer.cmd)</li>
</ol>
<p><img src="E:/YoudaoNote/pic/zookeeper/8.jpg" alt="image"></p>
<h6 id="上图表示服务治理-剔除无效服务-节点中可以再有子节点-的模型"><a href="#上图表示服务治理-剔除无效服务-节点中可以再有子节点-的模型" class="headerlink" title="上图表示服务治理(剔除无效服务,节点中可以再有子节点)的模型;"></a>上图表示服务治理(剔除无效服务,节点中可以再有子节点)的模型;</h6><ol start="7">
<li>三个启动好了后,进入第一个文件夹的bin里面启动zkCli.cmd;启动好了后如图：</li>
</ol>
<p><img src="E:/YoudaoNote/pic/zookeeper/9.jpg" alt="image"></p>
<ol start="8">
<li>右下角的框里出现那样的会话表示客户端也已经启动成功,输入</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">create /zk-node laowang</span><br></pre></td></tr></table></figure>
<p>这句命令后面还可以跟上其他命令比如权限什么的</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">ls /     --- “ls /”命令是查看当前根目录下面有哪些节点</span><br><span class="line"></span><br><span class="line">get /    ---   查看所有的节点数</span><br><span class="line"></span><br><span class="line">get /zk-node    --- 此命令是获取节点名为“ zk-node”的信息</span><br><span class="line"></span><br><span class="line">set /laowang2   ---  将当前节点中的信息(laowang)修改为laowang2</span><br><span class="line"></span><br><span class="line">delete /zk-node   --- 删除当前这个节点</span><br></pre></td></tr></table></figure>
<p>以上是在命令行中这样使用,在Java中使用是提供了一套工具包：==zkClient工具包==;如果是在代码中,在zookeeper里面有自带zookeeper.jar</p>
<h6 id="zk节点："><a href="#zk节点：" class="headerlink" title="zk节点："></a>zk节点：</h6><ul>
<li>持久节点 </li>
<li>临时节点(会话断开就消失，根据这个特点就可以服务治理，节点下面可以有数据(少量)，可以监听节点的变化，客户端可以拿到通知(拿到配置分发的实现))(配置管理原理)<br>节点名称是唯一的(分布式锁的原理，谁先来谁先得到)<br>节点可以有顺序，像是乐观锁和悲观锁 而且是分布式的</li>
</ul>
<h6 id="在Java代码中连接zookeeper-并且连接上-此处是持久化连接-若是临时接点可能一会儿就消失了不便于操作"><a href="#在Java代码中连接zookeeper-并且连接上-此处是持久化连接-若是临时接点可能一会儿就消失了不便于操作" class="headerlink" title="在Java代码中连接zookeeper,并且连接上(此处是持久化连接,若是临时接点可能一会儿就消失了不便于操作)"></a>在Java代码中连接zookeeper,并且连接上(此处是持久化连接,若是临时接点可能一会儿就消失了不便于操作)</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">public class Application &#123;</span><br><span class="line">    public static void main(String[] args) &#123;</span><br><span class="line">        //地址与端口配置</span><br><span class="line">        String zkServers = &quot;localhost:2181,localhost:2182,localhost:2183&quot;;</span><br><span class="line">        //加载地址;session保存时间;首次连接超时时间;序列化(节点什么传输(其他地方,Java在网络上传输对象要实现序列化与反序列化))</span><br><span class="line">        ZkClient zkClient = new ZkClient(zkServers, 10000, 10000, new SerializableSerializer());</span><br><span class="line">        System.out.println(&quot;connection OK&quot;);</span><br><span class="line"></span><br><span class="line">        User user = new User();</span><br><span class="line">        user.setId(1);</span><br><span class="line">        user.setName(&quot;songxiankun&quot;);</span><br><span class="line"></span><br><span class="line">        //配置节点 (模式有持久节点,临时节点等;ACL是权限配置)</span><br><span class="line">        String path = zkClient.create(&quot;/testNode&quot;,user, CreateMode.PERSISTENT);</span><br><span class="line">        //PERSISTENT:持久化;PERSISTENT_SEQUENTIAL:持久化序列;EPHEMERAL:临时节点</span><br><span class="line">        System.out.println(&quot;创建节点:&quot;+path);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>查看是否有这个节点：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Boolean b = zkClient.exists(&quot;/testNode&quot;);</span><br><span class="line">System.out.println(&quot;是否存在节点:&quot; + b);</span><br></pre></td></tr></table></figure></p>
<p>获取：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">User user = zkClient.readData(&quot;/testNode&quot;);</span><br><span class="line">    //之前指定了序列化,此处是反序列化成对象</span><br><span class="line">System.out.println(user.getName());</span><br></pre></td></tr></table></figure></p>
<p>删除：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">zkClient.delete(&quot;/testNode&quot;);</span><br></pre></td></tr></table></figure></p>
<p>数据更新修改：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">zkClient.writeData(&quot;/testNode&quot;, user);  </span><br><span class="line">//将信息包装成对象再放进去</span><br></pre></td></tr></table></figure>
<h6 id="监控节点-数量-变化："><a href="#监控节点-数量-变化：" class="headerlink" title="监控节点(数量)变化："></a>监控节点(数量)变化：</h6><ul>
<li>创建节点并加入节点监听机制：</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">User user = new User();</span><br><span class="line">    user.setId(2);</span><br><span class="line">    user.setName(&quot;/ppppppppppppp&quot;);</span><br><span class="line"></span><br><span class="line">    String path = zkClient.create(&quot;/twiceNode&quot;, user, CreateMode.PERSISTENT);</span><br><span class="line">    System.out.println(&quot;创建节点:&quot; + path);</span><br><span class="line">    zkClient.subscribeChildChanges(&quot;/twiceNode&quot;, new ZkListener());</span><br><span class="line">    Thread.sleep(Integer.MAX_VALUE);</span><br></pre></td></tr></table></figure>
<ul>
<li>配置监听(实现节点监听):</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">public class ZkListener implements IZkChildListener &#123;</span><br><span class="line">    /** 监听子节点的变化 */</span><br><span class="line">    public void handleChildChange(String parentPath, List&lt;String&gt; Children) throws Exception &#123;</span><br><span class="line">        System.out.println(parentPath);</span><br><span class="line">        /**监听子节点上面的数量变化*/</span><br><span class="line">        System.out.println(Children.toString());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li>此时,在客户端根目录下输入命令：</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">create /twiceNode/node1 123</span><br><span class="line">//解释:在节点下再创子节点： “twiceNode”在此处表示是父节点,是必须已经存在的,“node1”是新即将创建的子节点,“123”表示这个新的子节点上面带的值</span><br></pre></td></tr></table></figure>
<ul>
<li>IDEA输出：</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">/twiceNode</span><br><span class="line">[node1]</span><br><span class="line">//解释: 在父目录:/twiceNode中 成功创建了子节点“node1”</span><br></pre></td></tr></table></figure>
<p><img src="E:/YoudaoNote/pic/zookeeper/10.jpg" alt="image"></p>
<h6 id="监控节点-内容-变化："><a href="#监控节点-内容-变化：" class="headerlink" title="监控节点(内容)变化："></a>监控节点(内容)变化：</h6><ul>
<li>创建节点并加入数据监听机制：</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">User user = new User();</span><br><span class="line">        user.setId(4);</span><br><span class="line">        user.setName(&quot;/yyyyyyyyyyyy&quot;);</span><br><span class="line"></span><br><span class="line">        String path = zkClient.create(&quot;/FourNode&quot;, user, CreateMode.PERSISTENT);</span><br><span class="line">        System.out.println(&quot;创建节点:&quot; + path);</span><br><span class="line">        zkClient.subscribeDataChanges(&quot;/FourNode&quot;, new ZkDataListener());</span><br><span class="line">        Thread.sleep(3000);</span><br><span class="line">        zkClient.writeData(&quot;/FourNode&quot;, 456);</span><br><span class="line">        Thread.sleep(Integer.MAX_VALUE);</span><br></pre></td></tr></table></figure>
<ul>
<li>配置监听(实现内容监听):</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">public class ZkDataListener implements IZkDataListener &#123;</span><br><span class="line">    /** 数据发生修改的话的操作 */</span><br><span class="line">    public void handleDataChange(String dataPath, Object data) throws Exception &#123;</span><br><span class="line">        System.out.println(dataPath+&quot;-------&quot;+data);</span><br><span class="line">    &#125;</span><br><span class="line">    /** 数据被删除的话的操作 */</span><br><span class="line">    public void handleDataDeleted(String s) throws Exception &#123;</span><br><span class="line">        System.out.println(s);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<ul>
<li>当启动项目(运行主函数)后的效果：</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">创建节点:/FourNode</span><br><span class="line">/FourNode-------456</span><br><span class="line">//解释：第一行表示创建节点成功;第二行表示上面zkClient.writeData(&quot;/FourNode&quot;, 456);内容修改被监控打印</span><br></pre></td></tr></table></figure>
<ul>
<li>在命令行端修改内容：set /FourNode 789 不会有任何反应,是因为这个修改值要想有反应的话只有在代码中才可以;在命令行解密修改值是不会被监听打印到的</li>
<li>在命令行删除：</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">客户端输入     ： delete /FourNode</span><br><span class="line">IDEA被监控-打印：   /FourNode</span><br></pre></td></tr></table></figure>
<h4 id="4-zookeeper各种应用实践场景"><a href="#4-zookeeper各种应用实践场景" class="headerlink" title="4. zookeeper各种应用实践场景"></a>4. zookeeper各种应用实践场景</h4><h6 id="开源的分布式配置管理："><a href="#开源的分布式配置管理：" class="headerlink" title="开源的分布式配置管理："></a>开源的分布式配置管理：</h6><ul>
<li>百度的disconf </li>
<li><p>淘宝的diamond </p>
</li>
<li><p>[ ] 其实这两个都是浮云，后来阿里有了dubbo，然后当当网改进了dubbox(这两个都是专业于服务治理的);</p>
</li>
<li><p>[x] 然后现在有个一个全家桶的概念：SpringCloud ， 已经把dubbo(x)完全取代甩了几条大街了，什么网关啊服务代理啊什么东西之类的完全都有的(业界顶尖方案)</p>
</li>
</ul>
<h6 id="分布式治理："><a href="#分布式治理：" class="headerlink" title="分布式治理："></a>分布式治理：</h6><p><img src="E:/YoudaoNote/pic/zookeeper/11.jpg" alt="image"></p>
<p><strong>Master选举</strong></p>
<p><strong>分布式锁： 排他锁 共享锁</strong></p>
<ul>
<li>排他锁：是将其他锁阻塞在线程之外</li>
<li>共享锁： 允许其他锁来读，但是写的话还是要排队</li>
</ul>
<p>共享锁会涉及到 有序节点，在这个节点之中，zookeeper会自动给每个节点分配一个编号，这个编号是先来的会小；<br>如果这个节点(编号)前面有比这个编号还要小的节点的话，如果它在读，那么自己就放心的读，如果它在写，那么就只能等这个小的编号写完了，自己的这个大的编号才能够去读或者写</p>
<p>分布式队列：先进先出,完成任务后就删除</p>
<h6 id="zookeeper的节点："><a href="#zookeeper的节点：" class="headerlink" title="zookeeper的节点："></a>zookeeper的节点：</h6><ul>
<li style="list-style: none"><input type="checkbox" checked> ZooKeeper 节点是有生命周期的，这取决于节点的类型。</li>
<li>在 ZooKeeper中，节点类型可以分为持久节点（PERSISTENT ）、临时节点（EPHEMERAL），以及时序节点（SEQUENTIAL ），具体在节点创建过程中，一般是组合使用，可以生成以下 4 种节点类型。</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">1. 持久节点（PERSISTENT）</span><br><span class="line">2. 持久顺序节点（PERSISTENT_SEQUENTIAL）</span><br><span class="line">3. 临时节点（EPHEMERAL）</span><br><span class="line">4. 临时顺序节点（EPHEMERAL_SEQUENTIAL）</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">安装使用：</span><br><span class="line"></span><br><span class="line">1.在官网下载zookeeper稳定版(windows 和 linux 版本是通用的)</span><br><span class="line">2.复制成3分，并重命名123</span><br><span class="line">3.在根文件夹下文件夹data</span><br><span class="line">4.在conf文件夹下将zoo-simple.cfg重命名为zoo.cfg</span><br><span class="line">5.修改zoo.xml里面的端口号，3分分别为2181,2182,2183</span><br><span class="line">6.修改3分的datadir文件夹路径分别为三个不同的data路径</span><br><span class="line">7.添加集群配置文件:server.1=localhost:2887:3887</span><br><span class="line">server.2=localhost:2888:3889</span><br><span class="line">server.3=localhost:2889:3889</span><br><span class="line">#这个地方是集群配置</span><br><span class="line">#前面的端口号是连接端口号</span><br><span class="line">#后面的端口号是Master选举的端口号</span><br><span class="line">8.在每个data文件夹下新建文件myid,里面写入分别是1,2,3</span><br><span class="line">9.在启动的时候，3分都要启动才能启动成功</span><br></pre></td></tr></table></figure>

      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2018/03/08/work-attendance/" rel="next" title="work-attendance">
                <i class="fa fa-chevron-left"></i> work-attendance
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2018/03/12/redis/" rel="prev" title="redis">
                redis <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <p class="site-author-name" itemprop="name">S-Name Small·kk</p>
              <p class="site-description motion-element" itemprop="description">开源 | Java | 个人笔记 | 我的博客</p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/archives/">
              
                  <span class="site-state-item-count">12</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            

            

          </nav>

          

          

          
          

          
          

          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-5"><a class="nav-link" href="#1-分布式面临问题-CAP-BASE理论-zookeeper能做什么"><span class="nav-number">1.</span> <span class="nav-text">1.分布式面临问题 CAP/BASE理论 zookeeper能做什么</span></a><ol class="nav-child"><li class="nav-item nav-level-6"><a class="nav-link" href="#CAP理论："><span class="nav-number">1.1.</span> <span class="nav-text">CAP理论：</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#BASE理论："><span class="nav-number">1.2.</span> <span class="nav-text">BASE理论：</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#ACID和BASE的区别与联系"><span class="nav-number">1.3.</span> <span class="nav-text">ACID和BASE的区别与联系</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#zookeeper功能"><span class="nav-number">1.4.</span> <span class="nav-text">zookeeper功能:</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#分布式系统八大谬论"><span class="nav-number">1.5.</span> <span class="nav-text">分布式系统八大谬论:</span></a></li></ol></li><li class="nav-item nav-level-5"><a class="nav-link" href="#2-各种一致性协议解释"><span class="nav-number">2.</span> <span class="nav-text">2.各种一致性协议解释</span></a><ol class="nav-child"><li class="nav-item nav-level-6"><a class="nav-link" href="#高可用-一致性-取舍"><span class="nav-number">2.1.</span> <span class="nav-text">高可用 一致性 取舍</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#Paxos协议分为两个阶段："><span class="nav-number">2.2.</span> <span class="nav-text">Paxos协议分为两个阶段：</span></a></li></ol></li><li class="nav-item nav-level-5"><a class="nav-link" href="#3-zookeeper原理-安装使用"><span class="nav-number">3.</span> <span class="nav-text">3. zookeeper原理 安装使用</span></a><ol class="nav-child"><li class="nav-item nav-level-6"><a class="nav-link" href="#zookeeper如果是安装单机状态-就很容易保证上面的那5个特性-但是为了高可用就要用zookeeper来搭集群"><span class="nav-number">3.1.</span> <span class="nav-text">zookeeper如果是安装单机状态,就很容易保证上面的那5个特性;但是为了高可用就要用zookeeper来搭集群</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#上图表示服务治理-剔除无效服务-节点中可以再有子节点-的模型"><span class="nav-number">3.2.</span> <span class="nav-text">上图表示服务治理(剔除无效服务,节点中可以再有子节点)的模型;</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#zk节点："><span class="nav-number">3.3.</span> <span class="nav-text">zk节点：</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#在Java代码中连接zookeeper-并且连接上-此处是持久化连接-若是临时接点可能一会儿就消失了不便于操作"><span class="nav-number">3.4.</span> <span class="nav-text">在Java代码中连接zookeeper,并且连接上(此处是持久化连接,若是临时接点可能一会儿就消失了不便于操作)</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#监控节点-数量-变化："><span class="nav-number">3.5.</span> <span class="nav-text">监控节点(数量)变化：</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#监控节点-内容-变化："><span class="nav-number">3.6.</span> <span class="nav-text">监控节点(内容)变化：</span></a></li></ol></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-zookeeper各种应用实践场景"><span class="nav-number"></span> <span class="nav-text">4. zookeeper各种应用实践场景</span></a><ol class="nav-child"><li class="nav-item nav-level-6"><a class="nav-link" href="#开源的分布式配置管理："><span class="nav-number">0.1.</span> <span class="nav-text">开源的分布式配置管理：</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#分布式治理："><span class="nav-number">0.2.</span> <span class="nav-text">分布式治理：</span></a></li><li class="nav-item nav-level-6"><a class="nav-link" href="#zookeeper的节点："><span class="nav-number">0.3.</span> <span class="nav-text">zookeeper的节点：</span></a></li></ol></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2018</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">S-Name Small·kk</span>

  
</div>


  <div class="powered-by">由 <a class="theme-link" target="_blank" href="https://hexo.io">Hexo</a> 强力驱动</div>



  <span class="post-meta-divider">|</span>



  <div class="theme-info">主题 &mdash; <a class="theme-link" target="_blank" href="https://github.com/iissnan/hexo-theme-next">NexT.Pisces</a> v5.1.4</div>




        







        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>



  
  


  <script type="text/javascript" src="/js/src/affix.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/schemes/pisces.js?v=5.1.4"></script>



  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  





  

  

  

  
  

  

  

  

</body>
</html>
